package com.study.entity;

import com.study.frame.TankWarFrame;
import com.study.manager.ResourceManager;
import com.study.utils.ApplicationComponent;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 坦克
 * @Author ZhuHJay
 * @Date 2021/9/14 15:46
 */
public class Tank {

    /** 坦克的坐标 **/
    private int x, y;

    /** 坦克的大小 **/
    public static final int TANK_WIDTH = ResourceManager.myTankUP.getWidth();
    public static final int TANK_HEIGHT = ResourceManager.myTankUP.getHeight();

    /** 移动速度 **/
    private static final int SPEED = 10;

    /** 初始的运动方向 **/
    private Direction direction = Direction.UP;

    /** 展示的图片 **/
    private BufferedImage image = ResourceManager.myTankUP;

    /** 是否处于移动状态 **/
    private boolean isMoving = false;

    /** 该坦克是否能进行控制 **/
    private boolean control;

    /** 该坦克是否存活 **/
    private boolean living = true;

    /** 坦克的矩形 **/
    private Rectangle rectangle;

    /** 概率 **/
    private static final int FEN_ZI = 5;
    private static final int FEN_MU = 100;

    /** 随机函数 **/
    private Random random = new Random();

    /** 构造方法 **/
    public Tank(int x, int y, boolean control){
        this.x = x;
        this.y = y;
        this.control = control;
        rectangle = new Rectangle(x, y, TANK_WIDTH, TANK_HEIGHT);
    }

    /** 坦克应该拥有绘画自己的方法, 因为许多变量都只能自己进行修改 **/
    public void paint(Graphics graphics){
        // 判断坦克是否需要进行绘制
        if( !isLiving() ){
            TankWarFrame bean = ApplicationComponent.getBean(TankWarFrame.class);
            // 绘制爆炸
            bean.addExplode(new Explode(
                    getX() - (Explode.EXPLODE_WIDTH - Tank.TANK_WIDTH) / 2,
                    getY() - (Explode.EXPLODE_HEIGHT - Tank.TANK_HEIGHT) / 2));
            // 移除坦克
            bean.removeTank(this);
            return;
        }
        Color color = graphics.getColor();
        move();
        // 如果是敌机坦克, 那么就随机发射子弹以及随机移动
        randomMoveAndFire();
        graphics.drawImage(image, x, y, null);
        graphics.setColor(color);
    }

    private void randomMoveAndFire() {
        // 如果不是控制的坦克
        if( !control ){
            // 敌机随机发射子弹
            if( random.nextInt(FEN_MU) < FEN_ZI ){
                fire();
            }
            // 敌机随机改变方向
            if( random.nextInt(FEN_MU) < FEN_ZI ){
                Direction direction = Direction.values()[random.nextInt(4)];
                setDirection(direction);
                // 修改坦克的图片
                if( direction == Direction.UP ){
                    setImage(ResourceManager.tankUP);
                }else if( direction == Direction.LEFT ){
                    setImage(ResourceManager.tankLEFT);
                }else if( direction == Direction.DOWN ){
                    setImage(ResourceManager.tankDOWN);
                }else if( direction == Direction.RIGHT ){
                    setImage(ResourceManager.tankRIGHT);
                }
            }
        }
    }

    /** 坦克发射子弹 **/
    public void fire(){
        // 需要计算一下子弹的位置: 各个位置的发射位置都不同
        int bulletX = x;
        int bulletY = y;
        BufferedImage image = null;
        // 计算方向
        if( direction == Direction.UP ){
            image = ResourceManager.bulletUP;
            bulletX = x + (Tank.TANK_WIDTH - image.getWidth()) / 2 + 2;
            bulletY = y - image.getHeight() / 2;
        }else if( direction == Direction.RIGHT ){
            image = ResourceManager.bulletRIGHT;
            bulletX = x + (Tank.TANK_WIDTH - image.getWidth() / 2);
            bulletY = y + (Tank.TANK_HEIGHT - image.getHeight()) / 2 + 2;
        }else if( direction == Direction.DOWN ){
            image = ResourceManager.bulletDOWN;
            bulletX = x + (Tank.TANK_WIDTH - image.getWidth()) / 2 - 2;
            bulletY = y + (Tank.TANK_HEIGHT - image.getHeight() / 2);
        }else if( direction == Direction.LEFT ){
            image = ResourceManager.bulletLEFT;
            bulletX = x - image.getWidth() / 2;
            bulletY = y + (Tank.TANK_HEIGHT - image.getHeight()) / 2;
        }
        ApplicationComponent.getBean(TankWarFrame.class)
                .addBullet( new Bullet(bulletX, bulletY, direction, image, this) );
    }

    /** 坦克移动 **/
    private void move() {
        // 如果处于移动状态才需要进行移动
        if( !isMoving ){
            return;
        }
        // 判断当前的方向, 然后进行坐标的移动, 但是移动不能出界
        final int frameTop = 30;
        switch ( direction ){
            case DOWN:
                y += SPEED;
                // 判断是否超出范围
                if( y > TankWarFrame.FRAME_HEIGHT - Tank.TANK_HEIGHT ){
                    y = TankWarFrame.FRAME_HEIGHT - Tank.TANK_HEIGHT;
                }
                break;
            case UP:
                y -= SPEED;
                // 判断是否超出范围
                if( y < frameTop ){
                    y = frameTop;
                }
                break;
            case LEFT:
                x -= SPEED;
                // 判断是否超出范围
                if( x < 0 ){
                    x = 0;
                }
                break;
            case RIGHT:
                x += SPEED;
                // 判断是否超出范围
                if( x > TankWarFrame.FRAME_WIDTH - Tank.TANK_WIDTH ){
                    x = TankWarFrame.FRAME_WIDTH - Tank.TANK_WIDTH;
                }
                break;
            default:
                break;
        }
        // 移动完要重新赋值矩形
        rectangle.setBounds(x, y, TANK_WIDTH, TANK_HEIGHT);
    }

    /** 我与敌方坦克或者子弹与坦克的碰撞检测 **/
    public void bumpWith(Tank tank) {
        // 如果两个矩形相交, 那么就碰撞了
        if( rectangle.intersects(tank.rectangle) ){
//            living = false;
            tank.living = false;
        }
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }

    public void setImage(BufferedImage image) {
        this.image = image;
    }

    public void setMoving(boolean moving) {
        isMoving = moving;
    }

    public boolean isLiving() {
        return living;
    }

    public void setLiving(boolean living){
        this.living = living;
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    public boolean isControl() {
        return control;
    }
}
